package com.mgy.example.service.common.config.redis;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.mgy.example.constants.Constant;
import com.mgy.example.service.common.config.redis.RedisMessageReceiver;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis配置
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * 操作key-value都是对象
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值（默认使用JDK的序列化方式）
//        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
//        ObjectMapper mapper = new ObjectMapper();
//        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//        serializer.setObjectMapper(mapper);


        FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
        //设置默认序列化方案
        template.setDefaultSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());

        //设置序列化Value的实例化对象
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 操作key-value都是字符串
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }

    /**
     * redis消息监听器容器
     */
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //订阅了一个叫redis_lock通道
        container.addMessageListener(listenerAdapter, new PatternTopic(Constant.LOCK_CHANNEL));
        //这个container 可以添加多个消息监听适配器
        return container;
    }

    /**
     * 消息监听器适配器，绑定消息处理器，利用反射调用消息处理器的方法
     *
     * @param redisMessageReceiver redisMessageReceiver
     */
    @Bean
    MessageListenerAdapter listenerAdapter(RedisMessageReceiver redisMessageReceiver) {
        //messageListenerAdapter 传入一个消息接受的处理器，利用反射的方法调用方法“receiveMessage”
        return new MessageListenerAdapter(redisMessageReceiver, "receiveMessage");
    }

}
